package org.lcp.gatlingqueue.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.lcp.gatlingqueue.impl.part.BarrelImpl;
import org.lcp.gatlingqueue.impl.part.TurnplateImpl;
import org.lcp.gatlingqueue.interfaces.GatlingQueue;
import org.lcp.gatlingqueue.interfaces.action.HitHandle;
import org.lcp.gatlingqueue.interfaces.part.Barrel;
import org.lcp.gatlingqueue.interfaces.part.Turnplate;

/**
 * 简单实现
 * 
 * @author lcp
 * 
 * @param <T>
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SimpleGatlingQueueImpl<T> implements GatlingQueue<T> {

	// 目标list，默认只有一个目标
	List<HitHandle> targetList = new ArrayList<HitHandle>(1);

	// 枪管数量
	private int barrleCount = 0;

	// 卡口盘
	private Turnplate turnplate = new TurnplateImpl();

	// 线程池
	private ExecutorService pool = Executors.newFixedThreadPool(1);

	/**
	 * 构造函数
	 * 
	 * @param barrleCount
	 */
	public SimpleGatlingQueueImpl(int barrleCount) {

		if (barrleCount <= 0) {
			return;
		}
		this.barrleCount = barrleCount;

		Barrel[] barrelArray = new BarrelImpl[barrleCount];
		Barrel barrel;

		for (int i = 0; i < barrleCount; i++) {
			// 构造卡口
			barrel = new BarrelImpl(i);
			// clip.setBarrel(new BarrelImpl<Object>());
			barrelArray[i] = barrel;
		}

		for (int i = 0; i < barrleCount; i++) {
			// 把卡口装在盘上
			turnplate.addBarrel(barrelArray[i]);
		}

		// 执行后台监控线程
//		pool.execute(getBulletThread);
//		pool.shutdown();

	}

	// 监控强管理是否有子弹，打出去，击中瞄准目标
	private Runnable getBulletThread = new Runnable() {

		@Override
		public void run() {
			while (true) {
				// 循环得到下一个枪管里的子弹
				T bullet = (T) turnplate.next().out();
				if (bullet == null) {
					// 没子弹，进入下一次
					continue;
				}
				// 把子弹打到每一个瞄准的目标上，执行相应的动作
				try {
					for (HitHandle hitHandle : targetList) {
						// 被瞄准者被子弹击中时候发生的动作
						hitHandle.hit(bullet);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	};

	/**
	 * 开火
	 */
	@Override
	public void fire(T bullet) {
		turnplate.next().in(bullet);
	}

	/**
	 * 瞄准
	 */
	@Override
	public boolean sight(HitHandle target) {

		targetList.add(target);
		return true;
	}

	public List<Barrel> getAllBarrelCopy() {

		List<Barrel> list = new ArrayList<Barrel>(this.barrleCount);
		Barrel barrel = turnplate.next();

		do {
			list.add(barrel);
			barrel = turnplate.next();
		} while (list.contains(barrel) == false);

		return list;
	}
}
